﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IPC.Communication.Framework.BasicFramework;
using IPC.Communication.Framework.Core.Address;

namespace IPC.Communication.Framework.Profinet.Melsec.Helper
{
    public class McAsciiHelper
    {
        public static byte[] PackMcCommand(byte[] mcCore, byte networkNumber = 0, byte networkStationNumber = 0)
        {
            byte[] array = new byte[22 + mcCore.Length];
            array[0] = 53;
            array[1] = 48;
            array[2] = 48;
            array[3] = 48;
            array[4] = SoftBasic.BuildAsciiBytesFrom(networkNumber)[0];
            array[5] = SoftBasic.BuildAsciiBytesFrom(networkNumber)[1];
            array[6] = 70;
            array[7] = 70;
            array[8] = 48;
            array[9] = 51;
            array[10] = 70;
            array[11] = 70;
            array[12] = SoftBasic.BuildAsciiBytesFrom(networkStationNumber)[0];
            array[13] = SoftBasic.BuildAsciiBytesFrom(networkStationNumber)[1];
            array[14] = SoftBasic.BuildAsciiBytesFrom((ushort)(array.Length - 18))[0];
            array[15] = SoftBasic.BuildAsciiBytesFrom((ushort)(array.Length - 18))[1];
            array[16] = SoftBasic.BuildAsciiBytesFrom((ushort)(array.Length - 18))[2];
            array[17] = SoftBasic.BuildAsciiBytesFrom((ushort)(array.Length - 18))[3];
            array[18] = 48;
            array[19] = 48;
            array[20] = 49;
            array[21] = 48;
            mcCore.CopyTo(array, 22);
            return array;
        }

        public static byte[] ExtractActualDataHelper(byte[] response, bool isBit)
        {
            if (isBit)
            {
                return response.Select((byte m) => (byte)((m != 48) ? 1 : 0)).ToArray();
            }
            return MelsecHelper.TransAsciiByteArrayToByteArray(response);
        }

        public static OperateResult CheckResponseContent(byte[] content)
        {
            ushort num = Convert.ToUInt16(Encoding.ASCII.GetString(content, 18, 4), 16);
            if (num != 0)
            {
                return new OperateResult(num, MelsecHelper.GetErrorDescription(num));
            }
            return OperateResult.CreateSuccessResult();
        }

        public static byte[] BuildAsciiReadMcCoreCommand(McAddressData addressData, bool isBit)
        {
            return new byte[20]
		{
			48,
			52,
			48,
			49,
			48,
			48,
			48,
			(byte)(isBit ? 49 : 48),
			Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[0],
			Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[1],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[0],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[1],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[2],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[3],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[4],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[5],
			SoftBasic.BuildAsciiBytesFrom(addressData.Length)[0],
			SoftBasic.BuildAsciiBytesFrom(addressData.Length)[1],
			SoftBasic.BuildAsciiBytesFrom(addressData.Length)[2],
			SoftBasic.BuildAsciiBytesFrom(addressData.Length)[3]
		};
        }

        public static byte[] BuildAsciiReadMcCoreExtendCommand(McAddressData addressData, ushort extend, bool isBit)
        {
            return new byte[32]
		{
			48,
			52,
			48,
			49,
			48,
			48,
			56,
			(byte)(isBit ? 49 : 48),
			48,
			48,
			74,
			SoftBasic.BuildAsciiBytesFrom(extend)[1],
			SoftBasic.BuildAsciiBytesFrom(extend)[2],
			SoftBasic.BuildAsciiBytesFrom(extend)[3],
			48,
			48,
			48,
			Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[0],
			Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[1],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[0],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[1],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[2],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[3],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[4],
			MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[5],
			48,
			48,
			48,
			SoftBasic.BuildAsciiBytesFrom(addressData.Length)[0],
			SoftBasic.BuildAsciiBytesFrom(addressData.Length)[1],
			SoftBasic.BuildAsciiBytesFrom(addressData.Length)[2],
			SoftBasic.BuildAsciiBytesFrom(addressData.Length)[3]
		};
        }

        public static byte[] BuildAsciiWriteWordCoreCommand(McAddressData addressData, byte[] value)
        {
            value = MelsecHelper.TransByteArrayToAsciiByteArray(value);
            byte[] array = new byte[20 + value.Length];
            array[0] = 49;
            array[1] = 52;
            array[2] = 48;
            array[3] = 49;
            array[4] = 48;
            array[5] = 48;
            array[6] = 48;
            array[7] = 48;
            array[8] = Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[0];
            array[9] = Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[1];
            array[10] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[0];
            array[11] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[1];
            array[12] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[2];
            array[13] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[3];
            array[14] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[4];
            array[15] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[5];
            array[16] = SoftBasic.BuildAsciiBytesFrom((ushort)(value.Length / 4))[0];
            array[17] = SoftBasic.BuildAsciiBytesFrom((ushort)(value.Length / 4))[1];
            array[18] = SoftBasic.BuildAsciiBytesFrom((ushort)(value.Length / 4))[2];
            array[19] = SoftBasic.BuildAsciiBytesFrom((ushort)(value.Length / 4))[3];
            value.CopyTo(array, 20);
            return array;
        }

        public static byte[] BuildAsciiWriteBitCoreCommand(McAddressData addressData, bool[] value)
        {
            if (value == null)
            {
                value = new bool[0];
            }
            byte[] array = value.Select((bool m) => (byte)(m ? 49 : 48)).ToArray();
            byte[] array2 = new byte[20 + array.Length];
            array2[0] = 49;
            array2[1] = 52;
            array2[2] = 48;
            array2[3] = 49;
            array2[4] = 48;
            array2[5] = 48;
            array2[6] = 48;
            array2[7] = 49;
            array2[8] = Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[0];
            array2[9] = Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[1];
            array2[10] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[0];
            array2[11] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[1];
            array2[12] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[2];
            array2[13] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[3];
            array2[14] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[4];
            array2[15] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[5];
            array2[16] = SoftBasic.BuildAsciiBytesFrom((ushort)value.Length)[0];
            array2[17] = SoftBasic.BuildAsciiBytesFrom((ushort)value.Length)[1];
            array2[18] = SoftBasic.BuildAsciiBytesFrom((ushort)value.Length)[2];
            array2[19] = SoftBasic.BuildAsciiBytesFrom((ushort)value.Length)[3];
            array.CopyTo(array2, 20);
            return array2;
        }

        public static byte[] BuildAsciiReadRandomWordCommand(McAddressData[] address)
        {
            byte[] array = new byte[12 + address.Length * 8];
            array[0] = 48;
            array[1] = 52;
            array[2] = 48;
            array[3] = 51;
            array[4] = 48;
            array[5] = 48;
            array[6] = 48;
            array[7] = 48;
            array[8] = SoftBasic.BuildAsciiBytesFrom((byte)address.Length)[0];
            array[9] = SoftBasic.BuildAsciiBytesFrom((byte)address.Length)[1];
            array[10] = 48;
            array[11] = 48;
            for (int i = 0; i < address.Length; i++)
            {
                array[i * 8 + 12] = Encoding.ASCII.GetBytes(address[i].McDataType.AsciiCode)[0];
                array[i * 8 + 13] = Encoding.ASCII.GetBytes(address[i].McDataType.AsciiCode)[1];
                array[i * 8 + 14] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[0];
                array[i * 8 + 15] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[1];
                array[i * 8 + 16] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[2];
                array[i * 8 + 17] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[3];
                array[i * 8 + 18] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[4];
                array[i * 8 + 19] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[5];
            }
            return array;
        }

        public static byte[] BuildAsciiReadRandomCommand(McAddressData[] address)
        {
            byte[] array = new byte[12 + address.Length * 12];
            array[0] = 48;
            array[1] = 52;
            array[2] = 48;
            array[3] = 54;
            array[4] = 48;
            array[5] = 48;
            array[6] = 48;
            array[7] = 48;
            array[8] = SoftBasic.BuildAsciiBytesFrom((byte)address.Length)[0];
            array[9] = SoftBasic.BuildAsciiBytesFrom((byte)address.Length)[1];
            array[10] = 48;
            array[11] = 48;
            for (int i = 0; i < address.Length; i++)
            {
                array[i * 12 + 12] = Encoding.ASCII.GetBytes(address[i].McDataType.AsciiCode)[0];
                array[i * 12 + 13] = Encoding.ASCII.GetBytes(address[i].McDataType.AsciiCode)[1];
                array[i * 12 + 14] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[0];
                array[i * 12 + 15] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[1];
                array[i * 12 + 16] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[2];
                array[i * 12 + 17] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[3];
                array[i * 12 + 18] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[4];
                array[i * 12 + 19] = MelsecHelper.BuildBytesFromAddress(address[i].AddressStart, address[i].McDataType)[5];
                array[i * 12 + 20] = SoftBasic.BuildAsciiBytesFrom(address[i].Length)[0];
                array[i * 12 + 21] = SoftBasic.BuildAsciiBytesFrom(address[i].Length)[1];
                array[i * 12 + 22] = SoftBasic.BuildAsciiBytesFrom(address[i].Length)[2];
                array[i * 12 + 23] = SoftBasic.BuildAsciiBytesFrom(address[i].Length)[3];
            }
            return array;
        }

        public static OperateResult<byte[]> BuildAsciiReadMemoryCommand(string address, ushort length)
        {
            try
            {
                uint value = uint.Parse(address);
                byte[] array = new byte[20]
			{
				48,
				54,
				49,
				51,
				48,
				48,
				48,
				48,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0
			};
                SoftBasic.BuildAsciiBytesFrom(value).CopyTo(array, 8);
                SoftBasic.BuildAsciiBytesFrom(length).CopyTo(array, 16);
                return OperateResult.CreateSuccessResult(array);
            }
            catch (Exception ex)
            {
                return new OperateResult<byte[]>(ex.Message);
            }
        }

        public static OperateResult<byte[]> BuildAsciiReadSmartModule(ushort module, string address, ushort length)
        {
            try
            {
                uint value = uint.Parse(address);
                byte[] array = new byte[24]
			{
				48,
				54,
				48,
				49,
				48,
				48,
				48,
				48,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0
			};
                SoftBasic.BuildAsciiBytesFrom(value).CopyTo(array, 8);
                SoftBasic.BuildAsciiBytesFrom(length).CopyTo(array, 16);
                SoftBasic.BuildAsciiBytesFrom(module).CopyTo(array, 20);
                return OperateResult.CreateSuccessResult(array);
            }
            catch (Exception ex)
            {
                return new OperateResult<byte[]>(ex.Message);
            }
        }
    }
}
